﻿//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx. 
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
// See the License for the specific language governing rights and limitations under the License.
// 
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using NopSolutions.NopCommerce.BusinessLogic;
using NopSolutions.NopCommerce.BusinessLogic.Infrastructure;
using NopSolutions.NopCommerce.BusinessLogic.Model;
using NopSolutions.NopCommerce.BusinessLogic.SEO;
using NopSolutions.NopCommerce.BusinessLogic.Services;
using NopSolutions.NopCommerce.Common.Utils;

namespace NopSolutions.NopCommerce.Web
{
    public partial class BaseNopFrontendPage : BaseNopPage
    {
        #region Fields

        protected Stopwatch executionTimer;
        protected bool showExecutionTimer = false;
        private ISettingService _settingService;
        private ICustomerService _customerService;
        private IAffiliateService _affiliateService;

        #endregion

        #region Ctor

        public BaseNopFrontendPage() {
            _settingService = IoC.Resolve<ISettingService>();
            _customerService = IoC.Resolve<ICustomerService>();
            _affiliateService = IoC.Resolve<IAffiliateService>();

            showExecutionTimer = _settingService.GetSettingValueBoolean("Display.PageExecutionTimeInfoEnabled");
            if (showExecutionTimer) {
                executionTimer = new Stopwatch();
            }
        }

        #endregion

        #region Overrides

        protected override void OnPreInit(EventArgs e) {
            //store is closed
            if (_settingService.GetSettingValueBoolean("Common.StoreClosed")) {
                if (NopContext.Current.User != null &&
                    NopContext.Current.User.IsAdmin &&
                    _settingService.GetSettingValueBoolean("Common.StoreClosed.AllowAdminAccess")) {
                    //do nothing - allow admin access
                } else {
                    Response.Redirect("~/StoreClosed.htm");
                }
            }

            //SSL
            switch (this.SslProtected) {
                case PageSslProtectionEnum.Yes: {
                        CommonHelper.EnsureSsl();
                    }
                    break;
                case PageSslProtectionEnum.No: {
                        CommonHelper.EnsureNonSsl();
                    }
                    break;
                case PageSslProtectionEnum.DoesntMatter: {
                        //do nothing in this case
                    }
                    break;
            }

            //allow navigation only for registered customers
            if (_customerService.AllowNavigationOnlyRegisteredCustomers) {
                if (NopContext.Current.User == null || NopContext.Current.User.IsGuest) {
                    if (!this.AllowGuestNavigation) {
                        //it's not login/logout/passwordrecovery/captchaimage/register/accountactivation page (be default)
                        string loginURL = SEOHelper.GetLoginPageUrl(false);
                        Response.Redirect(loginURL);
                    }
                }
            }

            //theme
            //if (!String.IsNullOrEmpty(NopContext.Current.WorkingTheme)) {
            //    this.Theme = NopContext.Current.WorkingTheme;
            //}

            base.OnPreInit(e);
        }

        protected override void OnInit(EventArgs e) {
            if (showExecutionTimer) {
                executionTimer.Start();
            }

            if (!Page.IsPostBack) {
                CheckAffiliate();
            }

            //ClientDependencyLoader loader = new ClientDependencyLoader();

            //ClientDependencyPath path = new ClientDependencyPath();
            //path.Name = "Styles";
            //path.Path = "~/App_Themes/" + NopContext.Current.WorkingTheme;

            //loader.Paths.Add(path);

            //CssInclude cssStyle = new CssInclude();
            //cssStyle.Priority = 2;
            //cssStyle.PathNameAlias = "Styles";
            //cssStyle.FilePath = "style.css";

            //Header.Controls.Add(loader);
            //Header.Controls.Add(cssStyle);

            string defaulSEOTitle = _settingService.GetSettingValue("SEO.DefaultTitle");

            SEOHelper.RenderTitle(this.Page, defaulSEOTitle, false, false);
            SEOHelper.RenderMetaTag(this.Page, "description", _settingService.GetSettingValue("SEO.DefaultMetaDescription"), false);
            SEOHelper.RenderMetaTag(this.Page, "keywords", _settingService.GetSettingValue("SEO.DefaultMetaKeywords"), false);

            if (_settingService.GetSettingValueBoolean("Display.ShowNewsHeaderRssURL")) {
                SEOHelper.RenderHeaderRssLink(this.Page, defaulSEOTitle + ": News", SEOHelper.GetNewsRssUrl());
            }
            if (_settingService.GetSettingValueBoolean("Display.ShowBlogHeaderRssURL")) {
                SEOHelper.RenderHeaderRssLink(this.Page, defaulSEOTitle + ": Blog", SEOHelper.GetBlogRssUrl());
            }


            SetFavIcon();

            base.OnInit(e);

            RenderAnalyticsScript();

            if (showExecutionTimer) {
                executionTimer.Stop();
            }
        }

        protected override void OnLoad(EventArgs e) {
            if (showExecutionTimer) {
                executionTimer.Start();
            }

            base.OnLoad(e);

            if (showExecutionTimer) {
                executionTimer.Stop();
            }
        }

        protected override void CreateChildControls() {
            if (showExecutionTimer) {
                executionTimer.Start();
            }

            base.CreateChildControls();

            if (showExecutionTimer) {
                executionTimer.Stop();
            }
        }

        protected override void Render(HtmlTextWriter writer) {
            if (showExecutionTimer) {
                executionTimer.Start();
            }

            base.Render(writer);

            if (showExecutionTimer) {
                executionTimer.Stop();
                RenderExecutionTimerValue(writer);
            }
        }

        #endregion

        #region Utiilities

        protected void CheckAffiliate() {
            Affiliate affiliate = _affiliateService.GetAffiliateById(CommonHelper.QueryStringInt("AffiliateId"));
            if (affiliate != null && affiliate.Active) {
                if (NopContext.Current.User == null) {
                    HttpCookie affiliateCookie = HttpContext.Current.Request.Cookies.Get("NopCommerce.AffiliateId");
                    if (affiliateCookie == null)
                        affiliateCookie = new HttpCookie("NopCommerce.AffiliateId");

                    affiliateCookie.Value = affiliate.AffiliateId.ToString();
                    affiliateCookie.Expires = DateTime.Now.AddDays(10.0);
                    HttpContext.Current.Response.Cookies.Set(affiliateCookie);
                } else if (NopContext.Current.User.AffiliateId != affiliate.AffiliateId) {
                    NopContext.Current.User.AffiliateId = affiliate.AffiliateId;
                    _customerService.UpdateCustomer(NopContext.Current.User);
                }
            }
        }

        protected void RenderAnalyticsScript() {
            if (_settingService.GetSettingValueBoolean("Analytics.GoogleEnabled")) {
                string googleJS = _settingService.GetSettingValue("Analytics.GoogleJS");

                Literal script = new Literal() {
                    Text = googleJS
                };
                string placement = _settingService.GetSettingValue("Analytics.GooglePlacement").ToLowerInvariant();
                switch (placement) {
                    case "head": {
                            Header.Controls.Add(script);
                        }
                        break;
                    case "body":
                    default: {
                            Controls.Add(script);
                        }
                        break;
                }
            }
        }

        protected void SetFavIcon() {
            string favIconPath = HttpContext.Current.Request.PhysicalApplicationPath + "favicon.ico";
            if (File.Exists(favIconPath)) {
                string favIconUrl = CommonHelper.GetStoreLocation() + "favicon.ico";

                HtmlLink htmlLink2 = new HtmlLink();
                htmlLink2.Attributes["rel"] = "shortcut icon";
                htmlLink2.Attributes["href"] = favIconUrl;

                Page.Header.Controls.Add(htmlLink2);
            }
        }

        protected virtual void RenderExecutionTimerValue(HtmlTextWriter writer) {
            if (showExecutionTimer) {
                StringBuilder sb = new StringBuilder();
                sb.Append(@"<div style=""color:#fff;background:#000;font-weight:bold,padding:5px"">");
                sb.Append(String.Format("<p>Page execution time is {0}ms.</p>", executionTimer.Elapsed.TotalMilliseconds.ToString()));
                sb.Append(@"</div>");
                writer.Write(sb.ToString());
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets a value indicating whether this page is SSL protected
        /// </summary>
        public virtual PageSslProtectionEnum SslProtected {
            get {
                return PageSslProtectionEnum.DoesntMatter;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this page can be visited by anonymous customer when "Allow navigation only for registered customers" settings is set to true
        /// </summary>
        public virtual bool AllowGuestNavigation {
            get {
                return false;
            }
        }
        #endregion
    }
}